package cn.edu.dgut.sw.security.oauth2.weixin;

import java.util.List;
import java.util.Map;

import org.springframework.http.HttpMethod;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestTemplate;

/**
 * 微信网页登录授权的code与access_token的provider
 * 
 * @author dgsai
 * @date 2017-8-11
 */
public class WeiXinOAuth2AuthorizationCodeAccessTokenProvider extends AuthorizationCodeAccessTokenProvider {

	/**
	 * 源码分析：抛异常驱动重定向，根据异常信息构造重定向的url。 在向上一级filter传递异常前，截获此异常，更改异常中client_id为appid
	 * 
	 * @author dgsai
	 */
	@Override
	public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails details, AccessTokenRequest request)
			throws UserRedirectRequiredException, UserApprovalRequiredException, AccessDeniedException,
			OAuth2AccessDeniedException {
		
		try {
			return super.obtainAccessToken(details, request);
		} catch (UserRedirectRequiredException e) {
			Map<String, String> params = e.getRequestParams();
			String clientId = params.get("client_id");
			params.put("appid", clientId);
			params.remove("client_id");
			throw e;
		}
	}

	@Override
	protected ResponseExtractor<OAuth2AccessToken> getResponseExtractor() {
		List<HttpMessageConverter<?>> messageConverters = new RestTemplate().getMessageConverters();
		messageConverters.add(new WeiXinOAuth2MappingJackson2HttpMessageConverter());
		setMessageConverters(messageConverters);
		return super.getResponseExtractor();
	}

	// 微信登录授权获取access_token的方法为GET,重写此方法
	@Override
	protected HttpMethod getHttpMethod() {
		return HttpMethod.GET;
	}

}
